/*
* Copyright (C) 2008-2009 J-P Nurmi jpnurmi@gmail.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* $Id: completionmodel.cpp 506 2009-05-14 13:32:33Z jpnurmi $
*/

#include "completionmodel.h"
#include "application.h"
#include "command.h"
#include <QStandardItem>

CompletionModel::CompletionModel(QObject* parent)
    : QAbstractListModel(parent)
{
    init();
}

QStandardItem* CompletionModel::completionItem() const
{
    return d.item;
}

QStandardItemModel* CompletionModel::completionModel() const
{
    return d.model;
}

void CompletionModel::setCompletionModel(QStandardItemModel* model, QStandardItem* item)
{
    if (d.model != model)
    {
        if (d.model)
        {
            disconnect(d.model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(onDataChanged(QModelIndex,QModelIndex)));
            disconnect(d.model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(onRowsInserted(QModelIndex,int,int)));
            disconnect(d.model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(onRowsRemoved(QModelIndex,int,int)));
        }

        if (model)
        {
            connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(onDataChanged(QModelIndex,QModelIndex)));
            connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(onRowsInserted(QModelIndex,int,int)));
            connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(onRowsRemoved(QModelIndex,int,int)));
        }

        d.model = model;
        d.item = item;
        reset();
    }
}

int CompletionModel::rowCount(const QModelIndex& parent) const
{
    if (!d.model || parent.isValid())
        return 0;

    if (d.users == -1)
        d.users = d.item ? d.item->rowCount() : 0;
    if (d.channels == -1)
        d.channels = d.model->rowCount();
    return d.users + d.channels + d.commands.count() + d.aliases.count();
}

QVariant CompletionModel::data(const QModelIndex& index, int role) const
{
    if (d.users == -1)
        d.users = d.item ? d.item->rowCount() : 0;
    if (d.channels == -1)
        d.channels = d.model->rowCount();

    int row = index.row();
    if (row < d.users)
        return d.item->child(row, index.column())->data(role);

    row -= d.users;
    if (row < d.channels)
        return d.model->item(row, index.column())->data(role);

    static const QList<int> roles = QList<int>() << Qt::DisplayRole << Qt::EditRole;

    row -= d.channels;
    if (row < d.commands.count())
    {
        if (roles.contains(role) || role >= Qt::UserRole)
            return d.commands.at(row);
        return QVariant();
    }

    row -= d.commands.count();
    if (row < d.aliases.count())
    {
        if (roles.contains(role) || role >= Qt::UserRole)
            return d.aliases.at(row);
    }

    return QVariant();
}

void CompletionModel::onDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight)
{
    // TODO
    reset();
}

void CompletionModel::onRowsInserted(const QModelIndex& parent, int start, int end)
{
    // TODO
    reset();
}

void CompletionModel::onRowsRemoved(const QModelIndex& parent, int start, int end)
{
    // TODO
    reset();
}

void CompletionModel::init()
{
    d.model = 0;
    d.item = 0;
    d.aliases = Application::settings().aliases.keys();
    QMutableStringListIterator it1(d.aliases);
    while (it1.hasNext())
        it1.next().prepend("/");
    d.commands = Application::commands().keys();
    QMutableStringListIterator it2(d.commands);
    while (it2.hasNext())
        it2.next().prepend("/");
    d.channels = -1;
    d.users = -1;
}

void CompletionModel::reset()
{
    d.channels = -1;
    d.users = -1;
    QAbstractItemModel::reset();
}
